import { Controller, Get, Post, Res, Logger, Query, Body } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiQuery, ApiBody, ApiBearerAuth, ApiProduces } from '@nestjs/swagger';
import { FastifyReply } from 'fastify';
import { ExcelService } from './excel.service';
import * as ExcelJS from 'exceljs';
import { Public } from '~/modules/auth/decorators/public.decorator';
import { ModuleSwaggerTags } from '~/constants/modules.constant';
import { CreateCustomExcelDto, ExcelServiceStatusDto, ExcelHelpDto } from './excel.dto';

@ApiTags(ModuleSwaggerTags.EXCEL)
@ApiBearerAuth()
@Controller('excel')
export class ExcelController {
  private readonly logger = new Logger(ExcelController.name);

  constructor(private readonly excelService: ExcelService) {}

  /**
   * 测试创建Excel文件
   * @param res 响应对象
   * @param fileName 文件名（可选）
   */
  @Get('test/create')
	@Public()
  @ApiOperation({
    summary: '创建测试Excel文件',
    description: '生成包含示例数据的Excel文件并直接下载。包含员工信息示例数据，包括ID、姓名、邮箱、年龄、部门、创建时间等字段。'
  })
  @ApiQuery({
    name: 'fileName',
    required: false,
    description: '自定义文件名（不包含扩展名）',
    example: 'test-employees'
  })
  @ApiResponse({
    status: 200,
    description: 'Excel文件下载成功',
    headers: {
      'Content-Type': {
        description: 'MIME类型',
        schema: { type: 'string', example: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }
      },
      'Content-Disposition': {
        description: '文件下载配置',
        schema: { type: 'string', example: 'attachment; filename="test-excel-1640181234567.xlsx"' }
      }
    }
  })
  @ApiResponse({
    status: 500,
    description: '创建Excel文件失败',
    schema: {
      type: 'object',
      properties: {
        success: { type: 'boolean', example: false },
        message: { type: 'string', example: '创建Excel文件失败' },
        error: { type: 'string', example: '错误详细信息' }
      }
    }
  })
  @ApiProduces('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
  async testCreateExcel(
    @Res() res: FastifyReply,
    @Query('fileName') fileName?: string
  ) {
    this.logger.log('开始测试创建Excel文件');

    try {
      // 定义测试数据的列
      const columns: Partial<ExcelJS.Column>[] = [
        { header: 'ID', key: 'id', width: 10 },
        { header: '姓名', key: 'name', width: 15 },
        { header: '邮箱', key: 'email', width: 25 },
        { header: '年龄', key: 'age', width: 10 },
        { header: '部门', key: 'department', width: 15 },
        { header: '创建时间', key: 'createdAt', width: 20 }
      ];

      // 生成测试数据
      const testData = [
        {
          id: 1,
          name: '张三',
          email: 'zhangsan@example.com',
          age: 25,
          department: '技术部',
          createdAt: new Date().toISOString()
        },
        {
          id: 2,
          name: '李四',
          email: 'lisi@example.com',
          age: 28,
          department: '产品部',
          createdAt: new Date().toISOString()
        },
        {
          id: 3,
          name: '王五',
          email: 'wangwu@example.com',
          age: 30,
          department: '设计部',
          createdAt: new Date().toISOString()
        },
        {
          id: 4,
          name: '赵六',
          email: 'zhaoliu@example.com',
          age: 27,
          department: '运营部',
          createdAt: new Date().toISOString()
        },
        {
          id: 5,
          name: '钱七',
          email: 'qianqi@example.com',
          age: 29,
          department: '市场部',
          createdAt: new Date().toISOString()
        }
      ];

      // 创建工作簿
      const workbook = await this.excelService.createWorkbook(
        '员工信息表',
        columns,
        testData
      );

      // 转换为Buffer
      const buffer = await this.excelService.workbookToBuffer(workbook);      // 设置响应头
      const finalFileName = fileName || `test-excel-${Date.now()}.xlsx`;
      res.header('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      res.header('Content-Disposition', `attachment; filename="${finalFileName}"`);

      this.logger.log(`Excel文件创建成功，准备下载: ${finalFileName}`);

      // 发送文件
      return res.send(buffer);
    } catch (error) {
      this.logger.error('测试创建Excel文件失败', error);
      return res.status(500).send({
        success: false,
        message: '创建Excel文件失败',
        error: error.message
      });
    }
  }

  /**
   * 测试创建自定义Excel文件
   * @param body 请求体包含自定义数据
   * @param res 响应对象
   */
  @Post('test/custom')
  @Public()
  @ApiOperation({
    summary: '创建自定义Excel文件',
    description: '根据提供的自定义数据创建Excel文件并下载。支持自定义工作表名、列定义和数据内容。'
  })
  @ApiBody({
    type: CreateCustomExcelDto,
    description: '自定义Excel文件配置',
    examples: {
      '用户数据示例': {
        value: {
          sheetName: '用户信息表',
          columns: [
            { header: 'ID', key: 'id', width: 10 },
            { header: '姓名', key: 'name', width: 15 },
            { header: '邮箱', key: 'email', width: 25 },
            { header: '部门', key: 'department', width: 15 }
          ],
          data: [
            { id: 1, name: '张三', email: 'zhangsan@example.com', department: '技术部' },
            { id: 2, name: '李四', email: 'lisi@example.com', department: '产品部' }
          ],
          fileName: 'users.xlsx'
        }
      },
      '销售数据示例': {
        value: {
          sheetName: '销售报表',
          columns: [
            { header: '日期', key: 'date', width: 15 },
            { header: '产品', key: 'product', width: 20 },
            { header: '销量', key: 'quantity', width: 10 },
            { header: '金额', key: 'amount', width: 15 }
          ],
          data: [
            { date: '2025-06-22', product: '产品A', quantity: 100, amount: 5000 },
            { date: '2025-06-22', product: '产品B', quantity: 50, amount: 3000 }
          ],
          fileName: 'sales-report.xlsx'
        }
      }
    }
  })
  @ApiResponse({
    status: 200,
    description: '自定义Excel文件下载成功',
    headers: {
      'Content-Type': {
        description: 'MIME类型',
        schema: { type: 'string', example: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }
      },
      'Content-Disposition': {
        description: '文件下载配置',
        schema: { type: 'string', example: 'attachment; filename="custom-excel-1640181234567.xlsx"' }
      }
    }
  })
  @ApiResponse({
    status: 400,
    description: '请求参数错误',
    schema: {
      type: 'object',
      properties: {
        success: { type: 'boolean', example: false },
        message: { type: 'string', example: '列定义不能为空' }
      }
    }
  })
  @ApiResponse({
    status: 500,
    description: '创建自定义Excel文件失败',
    schema: {
      type: 'object',
      properties: {
        success: { type: 'boolean', example: false },
        message: { type: 'string', example: '创建自定义Excel文件失败' },
        error: { type: 'string', example: '错误详细信息' }
      }
    }
  })
  @ApiProduces('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
  async testCreateCustomExcel(
    @Body() body: CreateCustomExcelDto,
    @Res() res: FastifyReply
  ) {
    this.logger.log('开始测试创建自定义Excel文件');

    try {
      const { sheetName = '自定义数据表', columns, data, fileName } = body;

      // 验证输入数据
      if (!columns || !Array.isArray(columns) || columns.length === 0) {
        return res.status(400).send({
          success: false,
          message: '列定义不能为空'
        });
      }

      if (!data || !Array.isArray(data)) {
        return res.status(400).send({
          success: false,
          message: '数据不能为空'
        });
      }

      this.logger.debug(`自定义Excel参数 - 工作表: ${sheetName}, 列数: ${columns.length}, 数据行数: ${data.length}`);

      // 转换列定义格式
      const excelColumns: Partial<ExcelJS.Column>[] = columns.map(col => ({
        header: col.header,
        key: col.key,
        width: col.width || 15
      }));

      // 创建工作簿
      const workbook = await this.excelService.createWorkbook(
        sheetName,
        excelColumns,
        data
      );

      // 转换为Buffer
      const buffer = await this.excelService.workbookToBuffer(workbook);      // 设置响应头
      const finalFileName = fileName || `custom-excel-${Date.now()}.xlsx`;
      res.header('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      res.header('Content-Disposition', `attachment; filename="${finalFileName}"`);

      this.logger.log(`自定义Excel文件创建成功，准备下载: ${finalFileName}`);

      // 发送文件
      return res.send(buffer);
    } catch (error) {
      this.logger.error('测试创建自定义Excel文件失败', error);
      return res.status(500).send({
        success: false,
        message: '创建自定义Excel文件失败',
        error: error.message
      });
    }
  }

  /**
   * 获取Excel服务状态
   */
  @Get('status')
  @Public()
  @ApiOperation({
    summary: '获取Excel服务状态',
    description: '检查Excel服务是否正常运行，返回服务状态信息包括运行状态、时间戳、服务名称和版本号。'
  })
  @ApiResponse({
    status: 200,
    description: 'Excel服务状态信息',
    type: ExcelServiceStatusDto
  })
  getExcelServiceStatus() {
    this.logger.log('检查Excel服务状态');

    return {
      success: true,
      message: 'Excel服务运行正常',
      timestamp: new Date().toISOString(),
      service: 'ExcelService',
      version: '1.0.0'
    };
  }

  /**
   * 获取使用说明
   */
  @Get('help')
  @Public()
  @ApiOperation({
    summary: '获取Excel API使用说明',
    description: '获取所有可用的Excel API接口说明，包括接口描述、参数说明、请求示例等详细信息。'
  })
  @ApiResponse({
    status: 200,
    description: 'Excel API使用说明',
    type: ExcelHelpDto
  })
  getHelp() {
    this.logger.log('获取Excel API使用说明');

    return {
      success: true,
      message: 'Excel API 使用说明',
      endpoints: {
        'GET /excel/test/create': {
          description: '创建测试Excel文件并下载',
          parameters: {
            fileName: '可选，自定义文件名'
          },
          example: '/excel/test/create?fileName=my-test.xlsx'
        },
        'POST /excel/test/custom': {
          description: '创建自定义Excel文件并下载',
          body: {
            sheetName: '可选，工作表名称',
            columns: '必需，列定义数组',
            data: '必需，数据数组',
            fileName: '可选，文件名'
          },
          example: {
            sheetName: '用户数据',
            columns: [
              { header: 'ID', key: 'id', width: 10 },
              { header: '姓名', key: 'name', width: 15 }
            ],
            data: [
              { id: 1, name: '张三' },
              { id: 2, name: '李四' }
            ],
            fileName: 'users.xlsx'
          }
        },
        'GET /excel/status': {
          description: '检查Excel服务状态'
        },
        'GET /excel/help': {
          description: '获取API使用说明'
        }
      }
    };
  }
}
